package suncertify.view.server;

import suncertify.service.remote.Server;
import suncertify.service.remote.ServerAction;
import suncertify.util.Messages;
import suncertify.util.Notification;
import suncertify.view.AsyncActionListener;
import suncertify.view.SwingUtils;
import suncertify.view.SCButton;

import javax.swing.*;
import java.util.Observer;
import java.util.Observable;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

/**
 * Implementation of server window
 */
public class ServerWindow extends JFrame implements Observer {
    private static final Messages msg = Messages.getInstance();
    private static final String STATE_STOPED = msg.get("ui.server.state.stoped");
    private static final String STATE_STARTED = msg.get("ui.server.state.started");
    private static final Font statusFont = new Font("Courier New", Font.PLAIN, 11);
    private final JButton startButton;
    private final JButton stopButton;
    private final JLabel stateLabel;
    private final Server server;

    /**
     * constructor
     */
    public ServerWindow() {
        super(msg.get("ui.server.title"));
        JPanel pane = new JPanel();
        startButton = new SCButton(msg.get("ui.server.button.start"));
        stopButton = new SCButton(msg.get("ui.server.button.stop"));
        stopButton.setEnabled(false);
        stateLabel = new JLabel(STATE_STOPED);
        stateLabel.setFont(statusFont);
        stateLabel.setBorder(BorderFactory.createLoweredBevelBorder());

        server = Server.getIntance();
        server.addObserver(this);

        startButton.addActionListener(new AsyncActionListener() {
            public void doAsync(ActionEvent actionEvent) {
                server.start();
            }
        });

        stopButton.addActionListener(new AsyncActionListener() {
            public void doAsync(ActionEvent actionEvent) {
                server.stop();
            }
        });

        JPanel buttonPanel = new JPanel();
        buttonPanel.add(startButton);
        buttonPanel.add(stopButton);
        pane.setLayout(new BorderLayout());

        JPanel statePanel = new JPanel();
        statePanel.add(stateLabel);

        pane.add(buttonPanel, BorderLayout.CENTER);
        pane.add(stateLabel, BorderLayout.SOUTH);

        JMenuBar mb = new JMenuBar();
        mb.add(new ServerMenu(this));

        this.setJMenuBar(mb);
        this.setContentPane(pane);
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent windowEvent) {
                super.windowClosing(windowEvent);
                server.shutdown();
                System.exit(0);
            }
        });

        this.setResizable(false);
        this.pack();
        SwingUtils.placeCenter(this);
    }

    /**
     * updates the current view componen state
     * @param observable event source
     * @param o event object sent to observers
     */
    public void update(Observable observable, final Object o) {
        if (o instanceof Notification) {
            final JFrame frame = this;
            //all view updates must be done in swing thread
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    Notification notification = (Notification) o;
                    switch ((ServerAction) notification.getEvent()) {
                        case RMI_STARTED:
                            server.start();
                            break;
                        case RMI_CONNECT_ERROR:
                            int res = SwingUtils.showConfirm(frame, msg.get("rmi.not.started"));
                            if (res == 0) {
                                server.startRMI();
                            } else {
                                startButton.setEnabled(true);
                                startButton.requestFocus();
                            }
                            break;
                        case ERROR:
                            SwingUtils.showError(frame, notification.getMessage());
                            stopButton.setEnabled(server.isStarted());
                            startButton.setEnabled(!server.isStarted());
                            if (server.isStarted()) {
                                stateLabel.setText(STATE_STARTED);
                            } else {
                                stateLabel.setText(STATE_STOPED);
                            }
                            break;
                        case STARTING:
                        case STOPING:
                            startButton.setEnabled(false);
                            stopButton.setEnabled(false);
                            break;
                        case STARTED:
                            stopButton.setEnabled(true);
                            stopButton.requestFocus();
                            stateLabel.setText(STATE_STARTED);
                            break;
                        case STOPED:
                            startButton.setEnabled(true);
                            startButton.requestFocus();
                            stateLabel.setText(STATE_STOPED);
                            break;
                    }
                }
            });
        }
    }
}
